#pragma once
#include <unordered_map> 
#include <vector>
#include "User.hpp"
#include <pthread.h>

//频道管理模块
namespace chatroom
{
     //channel 
    class Channel 
    {
    private:
        std::unordered_map<int,User*> _users;  //uid 和 User映射
        int _rid; //频道/房间ID
        int _max; //房间最大人数

    public:
        Channel(int rid,int max) : _rid(rid) , _max(max) { } 
        bool FindUser(int uid)
        {
            auto it = _users.find(uid);
            if(it == _users.end()) return false;
            return true; 
        }
        bool AddUser(User* user)
        {
            logMessage(DEBUG,"adduser ，sock = %d",user->GetSock());
            if(_users.size() == _max) return false; 
            _users.insert({user->GetId(),user}); 
            return true;
        }
        bool RemoveUser(int uid)
        {
            auto it = _users.find(uid);
            if(it == _users.end()) return false; 
            _users.erase(it);
            return true;
        }

        void Broadcast(const std::string& broadcast,User* user)
        {
            std::string send;
            if(user != nullptr)
            {
                send = user->GetName() + "("  + std::to_string(user->GetId()) +")"+  " : " + broadcast;  
            }else send = broadcast;

            for(auto& it : _users)
            {
                logMessage(DEBUG,"正在为%d广播消息,sock : %d...",it.first,it.second->GetSock());
                write(it.second->GetSock(),send.c_str(),send.size()); 
            }
        }

        int UserNum(){return _users.size();} //返回房间用户数量

        int GetRid(){return  _rid;}
    };


    //频道管理模块
    class ManageChannel
    {
    private:
        std::unordered_map<int,Channel*> _channels;  //rid 和 channel映射
        //int _max;  //最多房间数量，暂时不使用
        pthread_mutex_t _mtx;

    public: 
        ManageChannel(){
            pthread_mutex_init(&_mtx,nullptr);
        }
        ~ManageChannel()
        {
            pthread_mutex_destroy(&_mtx);
        }
        //查找频道
        Channel* FindChannel(int rid)
        {
            pthread_mutex_lock(&_mtx);
            logMessage(DEBUG,"加锁成功");
            auto it = _channels.find(rid);
            if(it == _channels.end()) 
            {
                logMessage(DEBUG,"没找到房间");
                pthread_mutex_unlock(&_mtx);
                return nullptr;
            }else  
                pthread_mutex_unlock(&_mtx);
            logMessage(DEBUG,"找到了");
            return it->second; 
        }
        Channel* CreateChannel(int max_user,int rid) //创建一个频道
        {
            logMessage(DEBUG,"正在创建房间....");
            //max_user为房间人数最大数量
            Channel* ch = new Channel(rid , max_user);
            pthread_mutex_lock(&_mtx);
            _channels.insert({rid, ch}); 
            pthread_mutex_unlock(&_mtx);
            logMessage(DEBUG,"创建房间完毕....");
            return ch; 
        }

        bool RemoveChannel(int rid) //移除频道
        {
            pthread_mutex_lock(&_mtx);
             auto it = _channels.find(rid);
            if(it == _channels.end()) 
            {
                pthread_mutex_unlock(&_mtx);
                return false;
            }else 
            {
                _channels.erase(it);
                pthread_mutex_unlock(&_mtx);
            }
            return true;
        }

        //添加用户到指定频道
        bool AddUserToChannel(int rid , User* user)
        {
            logMessage(DEBUG,"添加用户，加锁...");
            pthread_mutex_lock(&_mtx);
            logMessage(DEBUG,"加锁成功，开始查找...");
            pthread_mutex_unlock(&_mtx);
            Channel* channel = FindChannel(rid);
            pthread_mutex_lock(&_mtx);
            if(channel == nullptr)
            {
                logMessage(DEBUG,"没有查找到rid");
                pthread_mutex_unlock(&_mtx);
                return false; 
            }else 
            {
                channel->AddUser(user);
                logMessage(DEBUG,"添加成功！用户已进入房间,sock = %d",user->GetSock());
                pthread_mutex_unlock(&_mtx);
            }
            return true;
        }

        //移除用户到指定频道
        bool RemoveUserFromChannel(User* user)
        {
            Channel* channel = FindChannel(user->GetRid());
            pthread_mutex_lock(&_mtx);
            if(channel == nullptr)
            {
                pthread_mutex_unlock(&_mtx);
                return false; 
            }else
            {
                logMessage(DEBUG,"正在把用户移除频道");
                channel->RemoveUser(user->GetId());
                //如果此时频道人数为0，销毁频道
                if(channel->UserNum() == 0)
                {
                    logMessage(DEBUG,"频道用户为0，移除频道");
                    pthread_mutex_unlock(&_mtx);
                    RemoveChannel(channel->GetRid());
                    pthread_mutex_lock(&_mtx);
                }
                logMessage(DEBUG,"设置用户在线状态");
                user->SetIsJoin(false);
                pthread_mutex_unlock(&_mtx);
            }
            return true;
        }

    };

   

};